/*------------------------------------------------------------------------
|                            FILE DESCRIPTION                            |
------------------------------------------------------------------------*/
/*------------------------------------------------------------------------
|  - File name     : os_object.c
|  - Author        : zeweni
|  - Update date   : 2021.05.05
|  - Copyright(C)  : 2021-2021 zeweni. All rights reserved.
------------------------------------------------------------------------*/
/*------------------------------------------------------------------------
|                            COPYRIGHT NOTICE                            |
------------------------------------------------------------------------*/
/*
 * Copyright (C) 2021, zeweni (17870070675@163.com)

 * This file is part of Ant Real Time Operating System.

 * Ant Real Time Operating System is free software: you can redistribute 
 * it and/or modify it under the terms of the Apache-2.0 License.

 * Ant Real Time Operating System is distributed in the hope that it will 
 * be useful,but WITHOUT ANY WARRANTY; without even the implied warranty 
 * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 
 * Apache-2.0 License License for more details.

 * You should have received a copy of the Apache-2.0 License.Ant Real Time
 * Operating System. If not, see <http://www.apache.org/licenses/>.
**/
/*------------------------------------------------------------------------
|                                INCLUDES                                |
------------------------------------------------------------------------*/

#include "os_object.h"
#include "os_cpu.h"
#include "os_mem.h"

#define  OS_OBJECT_CTN_THREAD_REPLACE(index1,index2)                        \
do{                                                                         \
    OS_Object_Ctn.Thread.List[index1] =  OS_Object_Ctn.Thread.List[index2]; \
    (OS_Object_t *) OS_Object_Ctn.Thread.List[index2] = OS_NULL;            \
}while(0)
					

/*------------------------------------------------------------------------
|                                  DATA                                  |
------------------------------------------------------------------------*/

/**
 * @brief    对象信息容器结构体。
 * @details  Object information container structure.
 * @note     Type数组的每一个成员，和结构体内的链表对象成员相互对应。
 *           比如: Type[0] <--> OS_Object_Thread_List。
 *           Each member of the Type array corresponds to the member of 
 *           the Threaded list object in the structure.
 *           Example: Type[0] <--> OS_Object_Thread_List.
**/
struct OS_Object_Info
{
	struct object
	{
		OS_Object_t *List[OS_THREAD_MAX_NUM]; /*!< 线程链表 */
		os_uint8_t  Num;                  /*!< 线程挂载的数量 */		
	}Thread;

};

/**
 * @brief    对象信息容器结构体,指针类型。
 * @details  Object information container structure,pointer type.
**/
typedef struct OS_Object_Info *OS_Object_Info_t;

/**
 * @brief    内核对象容器，所有对象的信息，都挂载在这上面。
 * @details  The kernel object container, all object information, is hung on it.
**/
static volatile struct OS_Object_Info OS_Object_Ctn = {0};


/*------------------------------------------------------------------------
|                              API FUNCTIONS                             |
------------------------------------------------------------------------*

/**
 * @brief     初始化对象,将其挂载在对象容器上。
 * @details   Initialize the object and mount it on the object container.
 * @param[in] object 要被初始化的对象地址。The address of the object.
 * @param[in] id     要被初始化的对象ID，不可重复。The ID of the object, cannot be repeated.
 * @param[in] type   要被初始化的对象类型。The type of object.
 * @return    [OS_OK]  对象初始化成功。The object is initialized successfully.
 * @return    [OS_NOK] 对象初始化失败。The object initialization failed.
**/
os_err_t OS_Object_Init(OS_Object_t *object,os_uint8_t id,os_uint8_t type)
{
	os_uint8_t index = 0;

	OS_ENTER_CRITICAL();
	
	for (index = 0; index < OS_Object_Ctn.Thread.Num; index++)
	{
		if ( (*OS_Object_Ctn.Thread.List[index])->Id ==  id)
		{
			return OS_NOK;
		}
	}
	
	(*object)->Id = id;
	(*object)->Type = type;
	
	OS_Object_Ctn.Thread.List[OS_Object_Ctn.Thread.Num++] = object;

	OS_EXIT_CRITICAL();

	return OS_OK;
}

/**
 * @brief     获取对象容器中线程的数量。
 * @details   Gets the number of threads in the object container.
 * @param[in] None.
 * @return    对象容器里线程的数量。The number of threads in the object container.
**/
os_uint8_t OS_Object_Get_Thread_Num_Info(void)
{
    return OS_Object_Ctn.Thread.Num;
}

/**
 * @brief     删除对象,将其从对象容器上脱离。
 * @details   Delete the object and detach it from the object container.
 * @param[in] type   对象类型。The type of object.
 * @return    [OS_OK]  对象删除成功。The object is detached successfully.
 * @return    [OS_NOK] 对象删除失败。The object detach failed.
**/
os_err_t OS_Object_Delete(OS_Object_t *object, enum OS_Object_Type type)
{
	os_uint8_t index = 0;

	OS_ENTER_CRITICAL();
	
	switch (type)
	{
		case OS_Object_Class_Thread:
		{
			for (index = 0; index < OS_Object_Ctn.Thread.Num; index++)
			{
				if (object == (OS_Object_t *)OS_Object_Ctn.Thread.List[index])
				{
                    OS_Object_Ctn.Thread.Num--;
					OS_OBJECT_CTN_THREAD_REPLACE(index,OS_Object_Ctn.Thread.Num);
				}
			}

			OS_EXIT_CRITICAL();
			return OS_OK;
		}
		default:break;
	}
	return OS_NOK;
}

/*------------------------------------------------------------------------
|                    END OF FLIE.  (C) COPYRIGHT zeweni                  |
------------------------------------------------------------------------*/